package com.codegenerate.demo.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.codegenerate.demo.config.R;
import com.codegenerate.demo.dto.*;
import com.codegenerate.demo.entity.GField;
import com.codegenerate.demo.entity.GTable;
import com.codegenerate.demo.service.GFieldService;
import com.codegenerate.demo.service.impl.GTableServiceImpl;
import com.codegenerate.demo.utils.StringUtils;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.apache.bcel.classfile.Field;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Slf4j
@Controller
@RequestMapping("/gTable")
public class GTableController {
    @Autowired
    GTableServiceImpl gTableService;
    @Autowired
    GFieldService gFieldService;


    @PostMapping("/list")
    @ResponseBody
    R<List<GTable>> list(@RequestBody GTableDto gTableDto){
        Page<GTable> page = gTableService.page(
                gTableDto.buildPage(),gTableDto.dto2entity().getQueryAll()
        );
        return R.ok(page.getRecords())
                .setCount(page.getTotal());
    }

    @GetMapping("/getItem")
    R<GTable> getItem(int id) {
        return R.ok(gTableService.getById(id));
    }



	@PostMapping("/add")
    @ResponseBody
    R<Boolean> add(@RequestBody  GTableDto gTableDto){
        var entity=gTableDto.dto2entity();
        //设置 默认
        GTable.setDefaultValue(entity);
        return R.ok(gTableService.save(entity));
    }


    @PostMapping("/update")
    @ResponseBody
    R<Integer> update(@RequestBody  GTableDto gTableDto){
        gTableDto.validateUpdate();
        return R.ok(gTableService.getBaseMapper().update(null, gTableDto.dto2entity().getUpdateWrapper()));
    }

    @GetMapping("/delbyid")
    R<Boolean> del(@RequestParam("id") int id) {

          var  result=gTableService.removeById(id);
          var query=new QueryWrapper<GField>().lambda();
             query.eq(GField::getgTableId,id);
          var ids=gFieldService.list(query).stream().map(item->item.getId())
                  .collect(Collectors.toList());
     var result2=   gFieldService.removeByIds(ids);

          return     R.ok(result2);
    }


    /**
     *  生成 代码压缩包
     * @return
     */
    @PostMapping("/zipCodeByTableId")
    @ResponseBody
    R<String> zipCodeByTableId(@RequestBody SystemFileDto fileDto) {

        var uuid= IdUtil.simpleUUID();
        var dicStr = "d:/generateCode/" + uuid;
        //regoin:  生产一个新的文件夹
//        FileUtil.touch(dicStr+"/");
         //endregoin

        //regoin:  把filelist写到文件夹下
        List<SystemFile> fileList = fileDto.getFileList();
        for (int i = 0; i < fileList.size(); i++) {
            var file = fileList.get(i);
            FileUtil.touch(dicStr+ "/" + file.getFileName());
            FileUtil.writeUtf8String(file.getFileContent(), dicStr+ "/" + file.getFileName());
        }
        //endregoin

        //regoin:  压缩zip 干掉临时文件夹
        var result= ZipUtil.zip(dicStr, dicStr+".zip");
        FileUtil.del(dicStr);
        //endregoin

        //region return 压缩包路径
        //endregion

        return R.ok("http://codeapi.liumingtai.com/static/"+uuid+".zip");
    }


    /**
     *  生成 代码压缩包
     * @return
     */
    @PostMapping("/zipCodeByTemplate")
    @ResponseBody
    R<String> zipCodeByTemplate(@RequestBody GenerateCodeDto templateCodeDto) {

        var uuid= IdUtil.simpleUUID();
        var dicStr = "d:/generateCode/" + uuid;
        //regoin:  生产一个新的文件夹
//        FileUtil.touch(dicStr+"/");
        //endregoin

        //regoin:  把filelist写到文件夹下
        List<SystemFile> fileList = templateCodeDto.getFileList();
        for (int i = 0; i < fileList.size(); i++) {
            var file = fileList.get(i);
            FileUtil.touch(dicStr+ "/" + file.getFileName());
            FileUtil.writeUtf8String(file.getFileContent(), dicStr+ "/" + file.getFileName());
        }
        //endregoin

        //regoin:  压缩zip 干掉临时文件夹
        var result= ZipUtil.zip(dicStr, dicStr+".zip");
        FileUtil.del(dicStr);
        //endregoin

        //region return 压缩包路径
        //endregion

        return R.ok("http://codeapi.liumingtai.com/static/"+uuid+".zip");
    }

    /**
     *  解析ddl
     * @return
     */
    @PostMapping("/paseddl")
    @ResponseBody
    R<DdlDto> parseDdl(@RequestBody DdlDto ddlDto){
        MySqlStatementParser parser = new MySqlStatementParser(ddlDto.getSql());
        List<SQLStatement> statementLists = parser.parseStatementList();
        var one=(MySqlCreateTableStatement)statementLists.get(0);
        ddlDto.setTableSource((String )one.getTableSource().getExpr().toString());

        var fileslist=new ArrayList<TableElement>();

        for (var  item : one.getTableElementList()) {
            try{
                var newOne=new TableElement();
                var adapterItem=(SQLColumnDefinition) item;
                newOne.setComment((String)adapterItem.getComment().toString());
                newOne.setName((String)adapterItem.getName().toString());
                newOne.setDateType((String)adapterItem.getDataType().toString());
                fileslist.add(newOne);

            }catch (RuntimeException e){
                 log.error(e.getMessage());
            }

        }

        ddlDto.setTableElementList(fileslist);
        return R.ok(ddlDto);
    }

    /**
     *  解析ddl
     * @return
     */
    @PostMapping("/addTableWithElementList")
    @ResponseBody
    R<Long> addTableWithElementList(@RequestBody DdlDto ddlDto){
        var tabeName=ddlDto.getTableSource();
        //region 校验是否存在 表名
        if(StringUtils.isEmpty(tabeName)){
            return R.failed("输入 tabeName");
        }
        var query=new QueryWrapper<GTable>().lambda();
        query.eq(GTable::getTableName,tabeName);
        var pageResult=gTableService.page(new Page<GTable>(1,1),query);
        var ones=pageResult.getRecords();
        if(ones!=null&&ones.size()>0&&ones.get(0)!=null){
            var one=ones.get(0);
            return R.failed("已存在表名");
        }

        //endregion


        //region 添加 表
       var newTable=new GTable();
        GTable.setDefaultValue(newTable);
        newTable.setTableName(ddlDto.getTableSource());
        gTableService.save(newTable);
        //endregion

        //region 添加 fileds
        var defailList=ddlDto.getTableElementList();
        var newDetailsLLIst=new ArrayList<GField >();
        for (int i = 0; i < defailList.size(); i++) {
            var one=new GField();
            GField.setDefaultValue(one);
            one.setgTableId(newTable.getId());
            one.setFiledName(defailList.get(i).getName());
            one.setFiledType(defailList.get(i).getFiledType());
            one.setFiledNameChinese(defailList.get(i).getComment());
            newDetailsLLIst.add(one);
        }
        var result2=gFieldService.saveBatch(newDetailsLLIst);
        //endregion



        return R.ok(1L);

    }
}




